import ast
import json  # 用于解析JSON消息
import threading
import time

import paho.mqtt.client as mqtt  # 用于连接和与MQTT代理服务器通信

import httpUtil
from Config import Config
from httpServer import CustomHTTPServer, MyHTTPRequestHandler
from modelHandler import ModelHandler  # 自定义模块，用于处理模型相关的数据


class DataHandler:  # 处理MQTT连接和消息处理
    serverIp = None
    serverPort = None
    username = None
    password = None
    clientId = None
    subTopic = None
    pushTopic = None
    properties = None
    httpPort = None

    def __init__(self, modelName):
        # 获取订阅主题以及关心的属性
        model = httpUtil.HttpClient.get_model(modelName)
        self.serverIp = model['mqttServer']
        self.serverPort = int(model['mqttPort'])
        self.username = model['username']
        self.password = model['password']
        self.clientId = model['clientId']
        self.subTopic = model['subTopic']
        self.pushTopic = model['pushTopic']
        self.properties = ast.literal_eval(model['properties'])
        self.httpPort = int(model['httpPort'])
        # self.serverIp = "123.60.177.231"
        # # self.serverIp = "192.168.1.66"
        # self.serverPort = 1886
        # self.username = "python_server&Nc2mzSAchh6"
        # self.password = "078ec5fc70c100da6436bae3a1a7da2e8089d99c914358c40e47fd5e128344d4"
        # self.clientId = "Nc2mzSAchh6.python_server|timestamp=1719471336581,clientType=device,securemode=2,signmethod=hmacsha256|"
        # self.subTopic = "/sys/Q85GoeQpBNw/+/thing/event/property/post"
        # self.pushTopic = "/sys/Q85GoeQpBNw/{deviceName}/thing/event/property/post"
        # self.properties = ['ecgData']  # 关心的属性列表

    # MQTT连接反馈
    def on_connect(self, client, userdata, flags, rc):
        if rc == 0:
            # 订阅主题
            for _ in range(5):
                time.sleep(1)
                client.subscribe(self.subTopic)
            print("连接成功")
        else:
            print("连接失败")

    # 消息监听
    def on_message(self, client, userdata, msg):
        if 'post_reply' in str(msg.topic):
            return
        print("收到消息: " + msg.topic + " " + str(msg.payload.decode()))
        json_data = json.loads(str(msg.payload.decode().replace('\'', '\"')))

        # 判断当前患者是否需要进行分析处理
        if int(json_data['deviceName']) not in Config.patientIds:
            return

        data = {'productKey': json_data['productKey'], 'deviceName': json_data['deviceName']}
        params = json_data['params']
        for _ in self.properties:
            if _ in params:
                data[_] = params[_]['value']
        self.handler_data(client, data)

    # 消息外推
    def push_message(self, client, pushTopic, result):
        client.publish(pushTopic, str(result))

    # 主题订阅
    def subscribe(self):
        client = mqtt.Client(client_id=self.clientId)
        client.username_pw_set(self.username, self.password)
        # 设置连接回调函数
        client.on_connect = self.on_connect
        # 设置回调函数
        client.on_message = self.on_message
        # 连接到MQTT代理服务器
        client.connect(self.serverIp, self.serverPort, 60)
        # 开始循环，处理消息
        client.loop_forever()

    # 数据解析及模型调用
    def handler_data(self, client, data):
        result = ModelHandler().handler_data(data)
        if result is None:
            return
            # 模型返回结果推送示例
        result = {
            "productKey": data["productKey"],
            "deviceName": data["deviceName"],
            "version": "1.0",
            "id": "602741957",
            "method": "thing.service.property.post",
            "params": {
                "atrialFibrillation": {
                    "value": str(result),
                    "time": 1719884285667,
                    "type": "string"
                }
            }
        }

        print(result)
        self.push_message(client, self.pushTopic.format(deviceName=data['deviceName']), result)

    def start_http(self):
        # 定义服务器地址和端口号
        server_address = ('', self.httpPort)
        # 创建HTTP服务器实例
        httpd = CustomHTTPServer(server_address, MyHTTPRequestHandler)
        # 启动HTTP服务器
        print('Starting server...', self.httpPort)
        httpd.serve_forever()

    def start_mqtt(self, modelHandler):
        modelHandler.subscribe()


if __name__ == '__main__':
    modelHandler = DataHandler(Config.modleName)
    # 创建并启动线程
    http_thread = threading.Thread(target=modelHandler.start_http)
    mqtt_thread = threading.Thread(target=modelHandler.start_mqtt, args=(modelHandler,))

    http_thread.start()
    mqtt_thread.start()

    # 等待线程完成
    http_thread.join()
    mqtt_thread.join()
